package com.wtwd.campus.service.impl;

import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.common.RespEntity;
import com.wtwd.campus.dao.DeviceClassPatternMapper;
import com.wtwd.campus.dao.DeviceInfoMapper;
import com.wtwd.campus.entity.DeviceClassMode;
import com.wtwd.campus.entity.DeviceClassPattern;
import com.wtwd.campus.entity.DeviceInfo;
import com.wtwd.campus.entity.SysUser;
import com.wtwd.campus.service.DeviceClassPatternService;
import com.wtwd.campus.service.RedisService;
import com.wtwd.campus.utils.CommandNumberUtil;
import com.wtwd.campus.utils.CommandSendUtils;
import com.wtwd.campus.utils.GeneralSequenceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mjy
 * @date 2021/06/25
 * @description
 */
@Service
public class DeviceClassPatternServiceImpl implements DeviceClassPatternService {

    @Autowired
    private DeviceClassPatternMapper classPatternMapper;
    @Autowired
    private CommandSendUtils commandSendUtils;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DeviceClassPatternMapper deviceClassPatternMapper;
    @Autowired
    private DeviceInfoMapper deviceInfoMapper;


    @Override
    public List<DeviceClassPattern> getDeviceClassesPatternByDeviceId(Integer deviceId) {
        return classPatternMapper.getDeviceClassPatternsByDeviceId(deviceId);
    }

    @Override
    public RespEntity deleteClassesPattern(Integer id, SysUser sysUser) {
        //判断设备是否在线(这里面id指主键id,并不是设备id)
        DeviceClassPattern classPattern = classPatternMapper.getDeviceClassPatternsById(id);
        if (classPattern != null) {
            DeviceInfo deviceInfo = deviceInfoMapper.getDeviceInfoByDeviceId(classPattern.getDeviceId());
            if (deviceInfo != null) {
                //鉴别设备是否在线
                boolean online = commandSendUtils.deviceOnline(deviceInfo.getImei());
                String commandNumber = getCurTime();
                commandSendUtils.delClassMode(deviceInfo.getImei(), commandNumber, classPattern.getSequence(), online, sysUser.getUserId(), false);
            }
        }
        //将该课堂模式中的状态改为待删除
        classPattern.setStatus(Constants.CLASSES_PATTERN_STAY_DELETE);
        Integer rest = classPatternMapper.updateClassPattern(classPattern);
        return new RespEntity(rest > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    @Override
    public Integer updateClassPatternStart(DeviceClassPattern deviceClassPattern) {
        return classPatternMapper.updateClassPattern(deviceClassPattern);
    }

    @Override
    public Integer deleteDeviceClassesPatternById(Integer id) {
        return classPatternMapper.deleteDeviceClassesPatternById(id);
    }

    @Override
    public Integer deleteDeviceClassesPatternByCommandNumber(String commandNumber) {
        return classPatternMapper.deleteDeviceClassesPatternByCommandNumber(commandNumber);
    }


    @Override
    public int addDeviceClassPattern(DeviceClassMode deviceClassMode) {
        return classPatternMapper.addDeviceClassPattern(deviceClassMode);
    }

    @Override
    public int updateClassPatternStatus(Integer deviceId, Integer sequence, Integer status, String commandNumber) {
        return classPatternMapper.updateDeviceClassPatternStatus(deviceId, sequence, status, commandNumber);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RespEntity addClassesPattern(String imei, Integer deviceId, List<DeviceClassMode> deviceClassPatterns, SysUser sysUser) {
        ArrayList<DeviceClassMode> batchAddList = new ArrayList<>();//批量添加集合,添加状态为待添加
        ArrayList<DeviceClassMode> batchUpdateList = new ArrayList<>();//批量修改课堂模式id,只修改状态，将状态值修改为待修改
        ArrayList<DeviceClassMode> bathDelList = new ArrayList<>();//记录批量删除课堂模式状态为待删除
        //查看该设备是否在线
        boolean online = commandSendUtils.deviceOnline(imei);//查看设备是否在线
        if (deviceClassPatterns != null && deviceClassPatterns.size() > 0) {
            List<DeviceClassMode> deviceClassPatternData = deviceClassPatternMapper.getDeviceClassPatternsByDeviceIdAndStatus(deviceId, null);
            if (deviceClassPatternData != null && deviceClassPatternData.size() > 0) {
                //以下代码是为了同步数据库状态与前端状态，过滤掉非正常状态数据(此过滤在数据库为空状态依旧执行，在外面过滤)
                Iterator<DeviceClassMode> iterator = deviceClassPatterns.iterator();
                while (iterator.hasNext()){
                    DeviceClassMode classMode = iterator.next();
                    for (DeviceClassMode deviceClass : deviceClassPatternData) {
                        if (classMode.getId()!=null&&deviceClass.getId().equals(classMode.getId())){//说明是同意组数据(当前端数据正常，后端数据不正常时,说明此数据正处在待状态，就算修改，依旧不予操作)
                            //更新数据库最新状态
                            classMode.setStatus(deviceClass.getStatus());
                            break;
                        }
                    }
                }
                //以下代码是为了鉴别是否需要添加到删除数据中心
                //数据库中存在，但是传过来没有
                //过滤非正常数据
                List<DeviceClassMode> collect = deviceClassPatternData.stream().filter(e -> e.getStatus().equals(Constants.CLASSES_PATTERN_NORMAl)).collect(Collectors.toList());
                for (DeviceClassMode deviceClassPattern : collect) {//数据库中的正常数据，如果前端没有传，则认为是要删除该数据
                    //定义删除标志
                    boolean flag = true;
                    for (DeviceClassMode classPattern : deviceClassPatterns) {
                        if (deviceClassPattern.getId().equals(classPattern.getId())) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {//收集删除数据
                        String commandNumber = CommandNumberUtil.getCurTime();
                        deviceClassPattern.setCommandNumber(commandNumber);
                        deviceClassPattern.setStatus(Constants.CLASSES_PATTERN_STAY_DELETE);
                        bathDelList.add(deviceClassPattern);
                        continue;
                    }
                }
            }
            //无论数据库是否有数据，都需要过滤掉非正常数据
            deviceClassPatterns= deviceClassPatterns.stream().filter(e -> e.getStatus().equals(Constants.CLASSES_PATTERN_NORMAl)).collect(Collectors.toList());
            System.out.println("课堂模式过滤掉后的正常数据:"+deviceClassPatterns);
            for (DeviceClassMode deviceClassPatternVo : deviceClassPatterns) {
                if (deviceClassPatternVo.getId() == null) {//此处为新增数据
                    //一台设备最多10台课堂模式
                    if (deviceClassPatternData != null && deviceClassPatternData.size() >= 10) {
                        return new RespEntity(RespCode.CLASS_PATTERN_MAXED);
                    }
                    if (deviceClassPatternData != null && deviceClassPatternData.size() > 0) {
                        for (DeviceClassMode deviceClassPattern : deviceClassPatternData) {
                            if (deviceClassPatternVo.getStartTime().equals(deviceClassPattern.getStartTime()) && deviceClassPatternVo.getEndTime().equals(deviceClassPattern.getEndTime())) {
                                return new RespEntity(RespCode.CLASS_PATTERN_EXIST);
                            }
                        }
                    }
                    //记录新增数据
                    List<Integer> sequenceList = deviceClassPatternData.stream().map(classPattern -> classPattern.getSequence()).collect(Collectors.toList());
                    int sequence = GeneralSequenceUtils.generalSequence(sequenceList);
                    String commandNumber = CommandNumberUtil.getCurTime();
                    deviceClassPatternVo.setCommandNumber(commandNumber);
                    //转化时间周期格式
                    String repeatTime = TimePeriodTool(deviceClassPatternVo.getRepeatTime());
                    deviceClassPatternVo.setRepeatTime(repeatTime);
                    deviceClassPatternVo.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
                    deviceClassPatternVo.setSequence(sequence);
                    deviceClassPatternVo.setOnOff(1);
                    batchAddList.add(deviceClassPatternVo);
                    //模拟添加到数据库
                    deviceClassPatternData.add(deviceClassPatternVo);
                } else {//此处为新增或者修改数据
                    //1.找出增加数据（带过来虽然有id但在数据库中没有这个id,说明这个数据被其他端删除掉了,需要重新增,如果其他端只是修改了,他处在修改状态，不记录)
                    boolean addFlag = true;
                    if (deviceClassPatternData != null && deviceClassPatternData.size() > 0) {
                        for (DeviceClassMode deviceClassMode : deviceClassPatternData) {
                            if (deviceClassMode.getId() != null) {//此处判空是因为，里面含有模拟新增数据
                                if (deviceClassMode.getId().equals(deviceClassPatternVo.getId())) {//存在此id数据则不进行新增操作
                                    addFlag = false;
                                    break;
                                }
                            }
                        }
                    }
                    if (addFlag) {
                        //记录新增数据
                        List<Integer> sequenceList = deviceClassPatternData.stream().map(classPattern -> classPattern.getSequence()).collect(Collectors.toList());
                        int sequence = GeneralSequenceUtils.generalSequence(sequenceList);
                        String commandNumber = CommandNumberUtil.getCurTime();
                        deviceClassPatternVo.setCommandNumber(commandNumber);
                        //转化时间周期格式
                        String repeatTime = TimePeriodTool(deviceClassPatternVo.getRepeatTime());
                        deviceClassPatternVo.setRepeatTime(repeatTime);
                        deviceClassPatternVo.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
                        deviceClassPatternVo.setSequence(sequence);
                        deviceClassPatternVo.setOnOff(1);
                        batchAddList.add(deviceClassPatternVo);
                        //模拟添加到数据库
                        deviceClassPatternData.add(deviceClassPatternVo);
                        continue;
                    }
                    //1.鉴别前端发送过来的数据是否需要去修改(在id一样的情况下,鉴别起始时间和重复时间是否一致)
                    //2.鉴别修改后的起始时间是否与其他课堂模式重复
                    Iterator<DeviceClassMode> iterator = deviceClassPatternData.iterator();
                    while (iterator.hasNext()) {//鉴别
                        DeviceClassMode classMode = iterator.next();
                        if (classMode.getId() != null && classMode.getId().equals(deviceClassPatternVo.getId())) {
                            //鉴别课堂模式是否发生修改
                            //鉴别课堂模式是否发生修改前转化周期重复时间
                            String time="";
                            if (deviceClassPatternVo.getRepeatTime()!=null){
                                time=TimePeriodTool(deviceClassPatternVo.getRepeatTime());
                            }
                            if (!(classMode.getStartTime().equals(deviceClassPatternVo.getStartTime()) && classMode.getEndTime().equals(deviceClassPatternVo.getEndTime()) && classMode.getRepeatTime().equals(time))) {
                                //记录修改数据
                                String commandNumber = CommandNumberUtil.getCurTime();
                                deviceClassPatternVo.setCommandNumber(commandNumber);
                                deviceClassPatternVo.setStatus(Constants.CLASSES_PATTERN_STAY_UPDATE);
                                //转化时间周期格式
                                String repeatTime = TimePeriodTool(deviceClassPatternVo.getRepeatTime());
                                deviceClassPatternVo.setRepeatTime(repeatTime);
                                batchUpdateList.add(deviceClassPatternVo);
                                //记录模拟修改数据库
                                classMode = deviceClassPatternVo;
                            }
                        }/* else {//记录与其他课堂模式起始时间是否有冲突
                            if (classMode.getStartTime().equals(deviceClassPatternVo.getStartTime()) && classMode.getEndTime().equals(deviceClassPatternVo.getEndTime())) {
                                return new RespEntity(RespCode.CLASS_PATTERN_EXIST);
                            }
                        }*/
                    }
                }
            }
        } else {//如果传过来的集合为空，则删除该设备的所有正常数据集合
            List<DeviceClassMode> deviceClassPatternList = deviceClassPatternMapper.getDeviceClassPatternsByDeviceIdAndStatus(deviceId, Constants.CLASSES_PATTERN_NORMAl);
            if (deviceClassPatternList != null && deviceClassPatternList.size() > 0) {
                for (DeviceClassMode deviceClassMode : deviceClassPatternList) {
                    deviceClassMode.setStatus(Constants.CLASSES_PATTERN_STAY_DELETE);
                    String commandNumber = CommandNumberUtil.getCurTime();
                    deviceClassMode.setCommandNumber(commandNumber);
                    bathDelList.add(deviceClassMode);
                }
            }
        }
        if (batchAddList != null && batchAddList.size() > 0) {
            for (DeviceClassMode deviceClassMode : batchAddList) {
                commandSendUtils.addClassMode(deviceClassMode, online, sysUser.getUserId(), false);
            }
            //批量新增
            deviceClassPatternMapper.batchAddClassesPattern(batchAddList);
        }
        if (batchUpdateList != null && batchUpdateList.size() > 0) {
            for (DeviceClassMode deviceClassMode : batchUpdateList) {
                commandSendUtils.updateClassMode(deviceClassMode, online, sysUser.getUserId(), false);
            }
            //批量修改，修改状态值和流水号
            deviceClassPatternMapper.batchUpdateClassesPatternState(batchUpdateList);
        }
        if (bathDelList != null && bathDelList.size() > 0) {
            for (DeviceClassMode deviceClassMode : bathDelList) {
                commandSendUtils.delClassMode(deviceClassMode.getImei(), deviceClassMode.getCommandNumber(), deviceClassMode.getSequence(), online, sysUser.getUserId(), false);
            }
            //批量删除，修改状态值，和流水号
            deviceClassPatternMapper.batchUpdateClassesPatternState(bathDelList);
        }
        return new RespEntity(RespCode.SUCCESS);
    }





    @Override
    public DeviceClassPattern getClassModeById(Integer id) {
        return classPatternMapper.getDeviceClassPatternsById(id);
    }

    @Override
    public int updateClassPatternStatus2(Integer id, Integer status, String commandNumber) {
        return classPatternMapper.updateDeviceClassPatternStatusById(id,status,commandNumber);
    }

    /**
     * repeat  [1,1,1,0,0,1,0] 转为 1110010
     *
     * @param repeatTime
     * @return
     */
    public String repeatTimeArray2String(Object[] repeatTime) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < repeatTime.length; i++) {
            stringBuffer = stringBuffer.append(repeatTime[i]);
        }
        return stringBuffer.toString();
    }

    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }

    /**
     * 时间周期转换工具
     *
     * @param week
     * @return
     */
    public String TimePeriodTool(String week) {
        //初始化一周工作时间
        int[] weekArray = new int[7];
        weekArray[0]=0;
        weekArray[1]=1;
        weekArray[2]=2;
        weekArray[3]=3;
        weekArray[4]=4;
        weekArray[5]=5;
        weekArray[6]=6;
        //初始化返回字符串
        String weekTime="";
        String[] split = week.split(",");
        for (int i = 0; i < weekArray.length; i++) {//保证返回数据长度至少有7位
            boolean flag=true;
            for (int j = 0; j < split.length; j++) {
                if (weekArray[i]==Integer.parseInt(split[j])){
                    weekTime+=1;
                    flag=false;
                    break;
                }
            }
            if (flag){
                weekTime+=0;
            }
        }
        return weekTime;
    }

    public static void main(String[] args) {

    }



}
